package service

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"reflect"
	"strings"
	"struct-generate-table-mysql/util"
	"sync"
	"text/template"
)

//获取结构体属性
func GetStructProperties(tmp interface{}) []map[string]string {
	var sliceTable []map[string]string

	//反射
	tableStruct := reflect.TypeOf(tmp)

	//驼峰转下划线
	sliceTable = make([]map[string]string, tableStruct.NumField()+1)
	t := make(map[string]string, 1)
	t["tableName"] = strings.ToUpper(util.CamelCase(tableStruct.Name()))
	sliceTable[0] = t

	for i := 0; i < tableStruct.NumField(); i++ {
		var table = make(map[string]string)
		//获取各个字段名称与属性
		field := tableStruct.Field(i)
		fieldType := fmt.Sprintf("%s", field.Type)
		table[strings.ToUpper(util.CamelCase(field.Name))] = fieldType
		sliceTable[i+1] = table
	}
	fmt.Println(sliceTable)
	return sliceTable
}

func CreateSql(table []map[string]string) string {
	var createSql string
	createSql = "CREATE TABLE `" + table[0]["tableName"] + "` ( \n"
	for x := 1; x < len(table); x++ {
		filed := table[x]

		for k, v := range filed {
			if k != "tableName" {
				var fieldType string
				//类型转换处理
				if v == "int" {
					fieldType = "INT(11)" //
				} else if v == "int32" {
					fieldType = "SMALLINT"
				} else if v == "int64" {
					fieldType = "BIGINT"
				} else if v == "float32" {
					fieldType = "FLOAT"
				} else if v == "float64" {
					fieldType = "DOUBLE"
				} else if v == "decimal.Decimal" {
					fieldType = "DECIMAL"
				} else if v == "int8" {
					fieldType = "TINYINT"
				} else if v == "byte" {
					fieldType = "BYTE"
				} else if v == "[]uint8" {
					fieldType = "BLOB"
				} else if v == "string" {
					fieldType = "varchar(200)"
				} else if v == "time.Time" {
					fieldType = "DATE"
				}

				createSql += "`" + k + "` " + fieldType + ", \n"

			}
		}
	}
	createSql += " PRIMARY KEY(`ID`) ) "
	return createSql
}

func CreateTable(tmp interface{}, wg *sync.WaitGroup) {
	table := GetStructProperties(tmp)
	sql := CreateSql(table)
	CreateFile(table[0]["tableName"], sql)
	wg.Done()
}

func CreateFile(tableName string, sql string) {

	file, err := os.Create("sqlCode/" + tableName + ".sql")
	defer file.Close()
	if err != nil {
		fmt.Errorf("文件创建失败 %v \n", err)
		return
	}
	_, err = io.WriteString(file, sql)
	if err != nil {
		fmt.Errorf("文件写入失败 %v \n ", err)
		return
	}

	fmt.Println("文件写入成功")
}

func CreateGo() {
	files, err := ioutil.ReadDir("./structs")
	if err != nil {
		fmt.Errorf("失败")
	}
	nameMap := make(map[string]string)
	for _, v := range files {

		tmp := strings.ReplaceAll(v.Name(), ".go", "")
		nameMap[strings.ToLower(tmp)] = tmp
	}

	info := make(map[string]map[string]string)
	info["structs"] = nameMap

	file, err := os.Create("./service/templateService.go")
	structTemplate, err1 := template.ParseFiles("./templates/service.txt")
	if err1 != nil {
		fmt.Println(err1)
	}
	//写入结构体
	structTemplate.Execute(file, info)
}
